<?php
/**
 *This controller is responsible for processing actions with themes
 *
 *@author Dmitry
 */
class Backend_ThemeController extends RCMS_Core_BaseController {

    private $_currentThemeName;

    private $_overwriteTheme;

    private $_uploadThemeName;

    private $_pathThemes;

	protected $_languageId;

	protected $_languageName;

	protected $_browseThemes;

    public function init()
    {
        parent::init();
        $this->_model = new Backend_ThemeModel();
		$this->_languageId = $this->_session->langId;
		$this->_languageName = strtolower($this->_languageId);
		if ($this->_languageName == '') {
			$this->_browseThemes  = 'swf-browse-themes.png';
		} else {
            $this->_browseThemes = 'swf-browse-themes'."-".$this->_languageName.".png";
			if (!file_exists('system/js/swfupload/'.$this->_browseThemes)) {
                $this->_browseThemes  = 'swf-browse-themes.png';
			}
		}
        $this->_currentThemeName = $this->_model->selectCurrentTheme();
        $this->_pathThemes       = $this->_config->website->website->path.$this->_config->website->website->themesPath;
    }

    /**
     * This function loads template for upload a theme.
     * @return void
     */
    public function indexAction()
    {
        $this->_checkLogin();
        $this->_helper->getHelper('layout')->disableLayout();
		$this->view->browseThemes = $this->_browseThemes;
        $this->view->success = $this->getRequest()->getParam('success');
        $this->view->listThemes = RCMS_Tools_FilesystemTools::scanDir($this->_pathThemes);
        $this->view->pathThemes = $this->_pathThemes;
        $this->view->currentThemeName = $this->_currentThemeName;
        $this->view->zipExtensionEnabled = (extension_loaded('zip')==true?true:false);
		$content = $this->_translator->processScreen($this->view->render($this->getViewScript()));
		$this->_helper->viewRenderer->setNoRender(true);
		echo $content;
    }

    /**
     * This function downloads a theme for user.
     * @return void
     */
    public function downloadthemeAction()
    {
        $this->_helper->getHelper('layout')->disableLayout();
        $this->_helper->viewRenderer->setNoRender(true);

        if ($this->getRequest()->isPost()) {
            $themeName = $this->getRequest()->getParam('name');
        }
        echo RCMS_Tools_FilesystemTools::createZip($themeName);
    }

    /**
     * This function uploads a theme and saves it into the filesystem.
     * @return void
     */
    public function uploadthemeAction()
    {
        $this->_helper->getHelper('layout')->disableLayout();
        $this->_helper->viewRenderer->setNoRender(true);

        $file = new Zend_File_Transfer_Adapter_Http();
        $data = $file->getFileInfo();
        $tmpFolder = $this->_config->website->website->path.$this->_config->website->website->tmp;

        $zip = new ZipArchive();
        $zip->open($data['Filedata']['tmp_name']);
        $zip->extractTo($tmpFolder);

        $this->_overwriteTheme = $this->getRequest()->getParam('overwrite');
        $check = $this->_validateTheme($tmpFolder);
        $this->_deleteThemeFromTmpFolder($tmpFolder);

        if (!empty($check)) {
            $zip->close();
            echo json_encode(array('error'=>$check['error'], 'message'=>$check['message'])); return;
        } else {
            if ($this->_overwriteTheme === 'true' && is_dir($this->_pathThemes.$this->_uploadThemeName)) {
                echo json_encode(array('error'=>false, 'exist_theme'=>true)); return;
            } else {
                $zip->extractTo($this->_pathThemes);
                $zip->close();
                $previewPicture = '';
                $listFilesInTheme = RCMS_Tools_FilesystemTools::scanDir($this->_pathThemes.$this->_uploadThemeName);

                foreach ($listFilesInTheme as $file) {
                    if (preg_match('/^preview\.(jpg|gif|png)$/', $file) && $previewPicture == '') {
                        $previewPicture = $file;
                        break;
                    }
                }
                RCMS_Tools_FilesystemTools::mkDir($this->_pathThemes.$this->_uploadThemeName.'/images/templatepreview/');

                if (file_exists($this->_pathThemes.$this->_uploadThemeName.'/'.$previewPicture)) {
                    $srcPreviewPicture = $this->_config->website->website->url.'themes/'.$this->_uploadThemeName.'/'.$previewPicture;
                } else {
                    $srcPreviewPicture = $this->_config->website->website->url.'system/images/noimage.png';
                }
                echo json_encode(array('error'=>false,'exist_theme'=>false,'theme'=>$this->_uploadThemeName,'preview'=>$srcPreviewPicture)); return;
            }
        }
    }

    /**
     * This function checks name of theme and returns array of errors.
     * @param type $folder
     * @return array
     */
    private function _validateTheme($folder)
    {
        if (!is_dir($folder)) {
            return array('error'=>true, 'message'=>'Can not create folder for unpack zip file. 0peration not permitted.');
        }

        $nameTheme = RCMS_Tools_FilesystemTools::scanDir($folder);
        if (count($nameTheme) > 1) {
            return array('error'=>true, 'message'=>'Your direrctory structure is invalid.');
        }

        $nameTheme = (string)$nameTheme[0];
        $listFiles = RCMS_Tools_FilesystemTools::scanDir($folder . $nameTheme);
        if (empty($listFiles)) {
            return array('error'=>true, 'message'=>'Your theme directory is empty.');
        }

        if (!preg_match("/^[a-zA-Z-0-9]{1,255}$/", $nameTheme)) {
            return array('error'=>true, 'message'=>'Theme name is invalid. Only letters, digits and dashes allowed.');
        }

        if (!file_exists($folder . $nameTheme . '/style.css')) {
            return array('error'=>true, 'message'=>'File "style.css" doesn\'t exits.');
        }

        if (!file_exists($folder . $nameTheme . '/index.html')) {
            return array('error'=>true, 'message'=>'File "index.html" doesn\'t exits.');
        }

        if (!file_exists($folder . $nameTheme . '/category.html')) {
            return array('error'=>true, 'message'=>'File "category.html" doesn\'t exits.');
        }

        if (!file_exists($folder . $nameTheme . '/default.html')) {
            return array('error'=>true,'message'=>'File "default.html" doesn\'t exits.');
        }

        if (!file_exists($folder . $nameTheme . '/news.html')) {
            return array('error'=>true,'message'=>'File "news.html" doesn\'t exits.');
        }

        if (!is_dir($folder . $nameTheme . '/images/')) {
            return array('error'=>true, 'message'=>'Directory "images" doesn\'t exits.');
        }

        if ($this->_overwriteTheme == 'false' && is_dir($this->_pathThemes . $nameTheme)) {
            return array('error'=>true, 'message'=>'Theme already exits.');
        }
        $this->_uploadThemeName = $nameTheme;
        return array();
    }

    /**
     * This function deletes a theme from filesystem.
     * @param string $path
     * @return void
     */
    private function _deleteThemeFromTmpFolder($path)
    {
        if (is_dir($path)) {
            if ($dir_handle = opendir($path)) {
                while (false !== ($file = readdir($dir_handle))) {
                    if ($file == '.' || $file == '..' || $file == '.svn') {
                        continue;
                    }
                    if (is_dir($path.$file)) {
                        $this->_deleteThemeFromTmpFolder($path.$file.'/');
                    } else {
                        @unlink($path.$file);
                    }
                }
                closedir($dir_handle);
                RCMS_Tools_FilesystemTools::rmDir($path);
            }
        }
    }

    /**
     * This function applys a theme.
     * @return void
     */
    public function selectthemeAction()
    {
        $this->_helper->getHelper('layout')->disableLayout();
        $this->_helper->viewRenderer->setNoRender(true);
        $this->_checkLogin();
        $success = null;

        if ($this->getRequest()->isPost() &&  trim($this->getRequest()->getParam('select_theme')) != '') {
            $selectTheme = trim($this->getRequest()->getParam('select_theme'));
        	$success = false;
	        if (is_dir($this->_pathThemes.$selectTheme)) {
            	if ($this->_saveThemeInDatabase($selectTheme)) {
            		$success = true;
            	}
	        }
        }
        $this->_forward('index', null, null, array('success' => $success));
    }

    /**
     * This function saves a theme into database.
     * @param string $theme
     * @return bollean
     */
    private function _saveThemeInDatabase($theme)
    {
        $listFiles = RCMS_Tools_FilesystemTools::scanDir($this->_pathThemes.$theme);
        $htmlFiles = array();

        foreach ($listFiles as $file) {
            if (preg_match('/^(.*)\.(html|htm)$/', $file)) {
                $htmlFiles[] = $file;
            }
        }

        if(empty($htmlFiles) || !in_array('index.html', $htmlFiles) ||
            !in_array('category.html', $htmlFiles) || !in_array('default.html', $htmlFiles) || !in_array('news.html', $htmlFiles))
        {
            return false;
        }

        $this->_model->updateCurrentThemeInConfigTable($theme);
        $this->_model->deleteTemplates();

        foreach ($htmlFiles as $file) {
            preg_match('/^(.*)\.(html|htm)$/', $file, $matches);

            if (count($matches) == 3 && isset($matches[1])) {
                $name = (string) $matches[1];
            } else {
                continue;
            }
            $name = RCMS_Tools_FilesystemTools::validateName($name);
            $exist = $this->_model->selectTemplateByName($name);

            if ($exist == 0) {
                $template = new RCMS_Object_Template_Template();
                $template->setName($name);
                $template->setTheme($theme);
                $template->setContent(trim(file_get_contents($this->_pathThemes.$theme.'/'.$file)));
                $template->setPreviewImage($this->determineImageForTheTemplate($this->_pathThemes.$theme.'/images/templatepreview/'.$name));
                $template->save();
                unset ($template);
            }
        }
        //process all pages with setting them corresponding template
        $pagesArray = $this->_model->selectAllPages();
        if ($pagesArray) {
            foreach ($pagesArray as $page) {
                if ($page['url'] != 'index') {
                    if ($this->_model->isCategory($page['category_id'])) {
                        $template = $this->_model->selectTemplateByTemplateName('category');
                        $this->_model->updateTemplateIdForPageTable($template['id'],$page['id']);
                    } else {
                        $template = $this->_model->selectTemplateByTemplateName('default');
                        $this->_model->updateTemplateIdForPageTable($template['id'],$page['id']);
                    }
                } else {
                    $template = $this->_model->selectTemplateByTemplateName('index');
                    $this->_model->updateTemplateIdForPageTable($template['id'],$page['id']);
                }
            }
        }
        // updating product pages with new product template
        $prodTemplate = $this->_model->selectTemplateByTemplateName('product');
        if ($prodTemplate) {
            $this->_model->updateTemplateForProductPages($prodTemplate['id']);
        }

        return true;
    }

    /**
     * This function finds preview image in theme.
     * @param string $imageName
     * @param string $currentTheme
     * @return string
     */
    public function determineImageForTheTemplate($path)
    {
        $image = '';
        if (is_file($path.'.jpg')) {
            $image =  basename($path.'.jpg');
        } elseif (is_file($path.'.gif')) {
            $image = basename($path.'.gif');
        } elseif (is_file($path.'.png')) {
            $image = basename($path.'.png');
        }
        return $image;
    }

    /**
     * This function deletes a theme from filesystem.
     * @return void
     */
    public function deletethemeAction()
    {
        $this->_helper->getHelper('layout')->disableLayout();
        $this->_helper->viewRenderer->setNoRender(true);
        $this->_checkLogin();

        if ($this->getRequest()->isPost() && trim($this->getRequest()->getParam('theme')) != '') {
            $theme = trim($this->getRequest()->getParam('theme'));
            if (is_dir($this->_pathThemes.$theme)) {
                $this->_deleteThemeFromTmpFolder($this->_pathThemes.$theme.'/');
            }
        }
    }
}